package com.xjrh.traintravel.collector.netty.handler;

import com.xjrh.traintravel.collector.common.CRC16M;
import com.xjrh.traintravel.collector.common.CodeConvertor;
import com.xjrh.traintravel.collector.common.ResultData;
import com.xjrh.traintravel.collector.netty.coder.Encoder;
import com.xjrh.traintravel.collector.netty.coder.command.AgreementCommandEnum;
import com.xjrh.traintravel.collector.netty.coder.command.AgreementConstant;
import com.xjrh.traintravel.collector.netty.coder.command.AgreementStructure;
import com.xjrh.traintravel.collector.netty.command.check.CheckApply;
import com.xjrh.traintravel.collector.netty.command.check.CheckData;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * 自检模式-指令处理类
 *
 * @author snps
 * @create 2022-02-07 14:06
 * @describe
 **/
@Component
@Slf4j
public class CheckHandler extends BaseAgreementHandler {

    /**
     * 创建命令：自检模式 启动/关闭
     * @param equipmentId 设备标识
     * @param checkType (1：启动，2：关闭）
     * @return AgreementStructure
     */
    public AgreementStructure buildCommand(String equipmentId, int checkType) {
        AgreementStructure agreement = new AgreementStructure();

        // 前导码(4)
        agreement.setPc(AgreementConstant.PC_VALUE);
        // 帧头(1)
        agreement.setSd(AgreementConstant.SD_VALUE);
        // 控制(1)
        agreement.setFc(AgreementCommandEnum.S_07.getValue());
        // MAC地址(6)
        agreement.setAddr(equipmentId);
        // 序号(1)
        // agreement.setSeq(CodeConvertor.intToHexString(1, 1));
        agreement.setSeq(super.getEquipmentSeq(agreement.getAddr()));
        // 长度(2)
        agreement.setLen(CodeConvertor.intToHexString(2, 2));
        // 数据(N)
        agreement.setData("01" + "0" + checkType);
        // 校验(2)
        String crcValue = CRC16M.calculateCrc(agreement);
        agreement.setFcs(crcValue);
        // 帧尾(1)
        agreement.setFs(AgreementConstant.FS_VALUE);

        return agreement;
    }

    /**
     * 发送 自检模式开/关 命令
     * @param agreement 命令
     * @return ResultData
     */
    public ResultData sendCheckCommand(AgreementStructure agreement) {
        /* 发送命令 */
        super.sendCommand(agreement);

        ResultData result = new ResultData(Boolean.TRUE);
        result.setResult(Boolean.TRUE);
        result.setInfo("发送指令成功！");
        result.setData(null);
        return result;
    }

    /**
     * 得到 自检模式-启动/关闭 响应
     * @param equipmentId 设备标识
     * @param applyData 响应数据
     * @return CheckApply
     */
    public CheckApply getCheckCommandApply(String equipmentId, String applyData) {
        CheckApply checkApply = new CheckApply();
        checkApply.setEquipmentId(equipmentId);
        checkApply.setCommonNo(applyData.substring(0, 2));
        checkApply.setResult(applyData.substring(2, 4));
        return checkApply;
    }

    /************************************************************
     * 得到 上报的数据
     * @param equipmentId 设备标识
     * @param data 上报数据
     * @return CheckData
     */
    public CheckData getCheckReportData(String equipmentId, String data) {
        CheckData checkData = new CheckData();
        checkData.setEquipmentId(equipmentId);
        checkData.setCommonNo(data.substring(0, 2));

        int v1, v2, v3;
        checkData.setType(Integer.parseInt(data.substring(2, 4), 16));
        v1 = Integer.parseInt(data.substring(4, 6), 16);
        v2 = Integer.parseInt(data.substring(6, 8), 16);
        v3 = Integer.parseInt(data.substring(8, 10), 16);
        checkData.setSoftwareVersion(v1 + "." + v2 + "." +v3);
        v1 = Integer.parseInt(data.substring(10, 12), 16);
        v2 = Integer.parseInt(data.substring(12, 14), 16);
        v2 = Integer.parseInt(data.substring(14, 16), 16);
        checkData.setHardwareVersion(v1 + "." + v2 + "." +v3);

        int hh, mm, ss;
        hh = Integer.parseInt(data.substring(16, 18), 16);
        mm = Integer.parseInt(data.substring(18, 20), 16);
        ss = Integer.parseInt(data.substring(20, 22), 16);
        StringBuilder sbuTime = new StringBuilder();
        sbuTime.append(hh >= 10 ? hh : "0" + hh).append(":");
        sbuTime.append(mm >= 10 ? mm : "0" + mm).append(":");
        sbuTime.append(ss >= 10 ? ss : "0" + ss);
        checkData.setTime(sbuTime.toString());

        checkData.setSpeedState(Integer.parseInt(data.substring(22, 24), 16));
        checkData.setFront1State(Integer.parseInt(data.substring(24, 26), 16));
        checkData.setFront2State(Integer.parseInt(data.substring(26, 28), 16));
        checkData.setMvbState(Integer.parseInt(data.substring(28, 30), 16));
        checkData.setSpeedValue(Integer.parseInt(data.substring(30, 34), 16));

        checkData.setStorage1State(Integer.parseInt(data.substring(34, 36), 16));
        checkData.setStorage1Space(Integer.parseInt(data.substring(36, 40), 16));
        checkData.setStorage1Surplus(Integer.parseInt(data.substring(40, 44), 16));
        checkData.setStorage2State(Integer.parseInt(data.substring(44, 46), 16));
        checkData.setStorage2Space(Integer.parseInt(data.substring(46, 50), 16));
        checkData.setStorage2Surplus(Integer.parseInt(data.substring(50, 54), 16));
        checkData.setDspState(Integer.parseInt(data.substring(54, 56), 16));
        checkData.setFront3State(Integer.parseInt(data.substring(56, 58), 16));
        checkData.setFront4State(Integer.parseInt(data.substring(58), 16));
        checkData.setCreateTime(new Date());
        return checkData;
    }

    /**
     * 创建命令：回复 上报数据 结果
     * @param agreement 收到的消息
     * @param channel 客户端连接通道
     */
    public void replyCheckReportData(AgreementStructure agreement, Channel channel) {
        AgreementStructure replyAgreement = new AgreementStructure();

        // 前导码(4)
        replyAgreement.setPc(AgreementConstant.PC_VALUE);
        // 帧头(1)
        replyAgreement.setSd(AgreementConstant.SD_VALUE);
        // 控制(1)
        replyAgreement.setFc(AgreementCommandEnum.R_87.getValue());
        // MAC地址(6)
        replyAgreement.setAddr(agreement.getAddr());
        // 序号(1)
        // replyAgreement.setSeq(CodeConvertor.intToHexString(1, 1));
        replyAgreement.setSeq(super.getEquipmentSeq(replyAgreement.getAddr()));
        // 长度(2)
        replyAgreement.setLen(CodeConvertor.intToHexString(2, 2));
        // 数据(N)
        replyAgreement.setData("02" + "01");
        // 校验(2)
        String crcValue = CRC16M.calculateCrc(replyAgreement);
        replyAgreement.setFcs(crcValue);
        // 帧尾(1)
        replyAgreement.setFs(AgreementConstant.FS_VALUE);

        /* 发送命令 */
        super.sendCommand(replyAgreement, channel);
    }

}